<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>策略模式</title>
</head>

<body>
  <script>
    // 绩效为 S 的人，年终奖有4倍工资
    // 绩效为 A 的人，年终奖有3倍工资
    // 绩效为 B 的人，年终奖有2倍工资
    /* var calculate = function(level,salary){
      if(level == 'S') return salary*4
      if(level == 'A') return salary*3
      if(level == 'B') return salary*2
    }
    console.log(calculate('S',20000)) */

    /* // 采用策略模式重构
    var pS = function(){};
    pS.prototype.calculate = function(salary){
      return salary*4
    }
    var pA = function(){};
    pA.prototype.calculate = function(salary){
      return salary*3
    }
    var pB = function(){};
    pB.prototype.calculate = function(salary){
      return salary*2
    }
    var Bouns = function(){
      this.salary = null;  // 初始的薪水
      this.strategy = null;  // 绩效等级的策略对象
    }
    Bouns.prototype.setSalary = function(salary){
      this.salary = salary
    }
    Bouns.prototype.setStrategy = function(strategy){
      this.strategy = strategy
    }
    Bouns.prototype.getBouns = function(){
      return this.strategy.calculate(this.strategy)
    }

    var bouns = new Bouns();
    bouns.setSalary(10000)
    bouns.setStrategy(new pS())
    console.log(bouns.getBouns()) */

    // 函数也是对象
    /* var strategy = {
      "S":function(salary){
        return salary*4
      },
      "A":function(salary){
        return salary*3
      },
      "B":function(salary){
        return salary*2
      }
    }
    var getBouns = function(level,salary){
      return strategy[level](salary)
    }
    console.log(getBouns('S',10000)) */
  </script>
  <form action="xxx.com" method="post" id="registerForm">
    请输入用户名：<input type="text" name="username">
    请输入密码：<input type="password" name="password">
    请输入电话号码：<input type="tel" name="phonenumber">
    <button>提交</button>
  </form>
  <script>
    // 表单验证的封装
    /* var registerForm = document.getElementById('registerForm');
    registerForm.onsubmit = function () {
      if (registerForm.username.value === '') {
        alert('用户名不能为空')
        return false
      }
      if (registerForm.password.value.length < 6) {
        alert('密码长度不能小于6')
        return false
      }
      if (!/^1[3|5|8][0-9]{9}$/.test(registerForm.phonenumber.value)) {
        alert('手机号格式不正确')
        return false;
      }
    } */
    // 运用策略模式封装
    var registerForm = document.getElementById('registerForm');
    var strategies = {
      isNoneEmpty: function (value, errorMsg) {
        if (value == '') {
          return errorMsg
        }
      },
      minLength: function (value, errorMsg) {
        if (value.length < 6) {
          return errorMsg
        }
      },
      isMobile: function (value, errorMsg) {
        if (!/^1[3|5|8][0-9]{9}$/.test(value)) {
          return errorMsg
        }
      }
    }

    // 假设 （无中生有） 假设我有一个验证类  new Validator()
    var validator = function(){
      var validator = new Validator()
      // 添加验证规则
      validator.add(registerForm.username,'isNoneEmpty','用户名不能为空')
      validator.add(registerForm.password,'minLength:6','密码长度不能小于6')
      validator.add(registerForm.phonenumber,'isMobile','手机号格式不正确')
      // 开启验证
      var errorMsg = validator.start()
      return errorMsg
    }
    registerForm.onsubmit = function(){
      var errorMsg = validator()
      if(errorMsg){
        alert(errorMsg)
        return false
      }
    }

    // 封装策略类  构造函数  class
    var Validator = function(){
      // 保存验证规则的数组
      this.cache = [];
    }
    Validator.prototype.add = function(dom,rule,errorMsg){
      var ary = rule.split(':')
      this.cache.push(function(){
        var strategy = ary.shift() // 用户选择的验证规则
        ary.unshift(dom.value)
        ary.push(errorMsg)
        return strategies[strategy].apply()
      })
    }
    
    Validator.prototype.start = function(){
      for(var i = 0,vaFunc;vaFunc = this.cache[i++];){
        var msg = vaFunc();
        if(msg) return msg;
      }
    }

  </script>
</body>

</html>